#include "electronicscaledataprocesspage.h"
#include "moduleelectronicscalelichen.h"
#include "moduleelectronicscaleshimadzu.h"
#include "moduleelectronicscaledefine.h"
#include "moduleelectronicscaleconfigid.h"
#include "moduleelectronicscaleeventid.h"
#include "modulemanager.h"
#include "electronicscaletool.h"
#include "mainwindow.h"
#include <QDebug>
#include <QMessageBox>

ElectronicScaleDataProcessPage::ElectronicScaleDataProcessPage(QWidget *parent)
    : QWidget(parent)
{
    setWindowTitle(tr("ElectronicScale Data Process Page"));
    setAttribute(Qt::WA_DeleteOnClose);

    m_curve = new Curve();
    QCustomPlot &cp = m_curve->getQCustomPlot();
    QSharedPointer<QCPAxisTickerDateTime> ticker(new QCPAxisTickerDateTime);
    ticker->setDateTimeFormat("hh:mm:ss");
    ticker->setDateTimeSpec(Qt::LocalTime);
    ticker->setTickCount(24);
    ticker->setTickStepStrategy(QCPAxisTicker::tssMeetTickCount);
    cp.xAxis->setTickLabelRotation(35);
    cp.xAxis->setTicker(ticker);
    m_curve->setTitle(tr("Weight & Interval Rate Curve"));
    m_curve->setXAxisName(tr("Time"));
    m_curve->setYAxisName(tr("Weight(g)/Interval Rate(g/h)"));
    m_curve->addGraph(tr("Weight"), QColor(Qt::red));
    m_curve->addGraph(tr("Interval Rate"), QColor(Qt::green));
    m_curve->addGraph(tr("Select Hour Weight"), QColor(Qt::blue));
    mainwindow->addSubWindow(m_curve);
    m_curve->show();

    m_curveHornDiagram = new Curve();
    m_curveHornDiagram->setTitle(tr("Horn Diagram Curve"));
    m_curveHornDiagram->setXAxisName(tr("Viewing Window(min)"));
    m_curveHornDiagram->setYAxisName(tr("Error(%)"));
    m_curveHornDiagram->addGraph(tr("Ep(max)"), QColor(Qt::red));
    m_curveHornDiagram->addGraph(tr("Ep(min)"), QColor(Qt::green));
    m_curveHornDiagram->addGraph(tr("Total Average Error"), QColor(Qt::blue));
    mainwindow->addSubWindow(m_curveHornDiagram);
    m_curveHornDiagram->show();

    m_lbInterval = new QLabel(tr("Interval(s)"));
    m_leInterval = new QLineEdit();
    m_leInterval->setText(QString::number(30));

    m_pbImportWeight = new QPushButton(tr("Import Weight Data"));
    connect(m_pbImportWeight, &QPushButton::clicked, this, [=](){
        if (m_importWeightPath.isEmpty())
            m_importWeightPath = QDir::currentPath();
        QString path = QFileDialog::getOpenFileName(nullptr, tr("Import file"), m_importWeightPath);
        if (path.isEmpty())
            return;
        m_importWeightPath = path;

        m_samples.clear();
        m_rates.clear();

        m_curve->onClear(2);
        m_curveHornDiagram->onClear(3);

        ElectronicScaleTool::importWeightDataFromXlsx(path, m_samples);

        foreach (auto sample, m_samples)
        {
            QDateTime t = QDateTime::fromMSecsSinceEpoch(sample.time);
            double time = QCPAxisTickerDateTime::dateTimeToKey(t);
            m_curve->onAddGraphPoint(0, time, sample.weight.value);
        }
        m_curve->onFullScreen(0);
    });

    m_pbCalculateIntervalRate = new QPushButton(tr("Calculate Interval Rate"));
    connect(m_pbCalculateIntervalRate, &QPushButton::clicked, this, [=](){
        bool ok;
        quint32 interval = m_leInterval->text().toUInt(&ok);
        if (!ok || interval == 0)
            return;
        if (m_samples.size() < 2)
            return;
        m_rates = ElectronicScaleIntervalRate::calculate(m_samples, interval);

        m_curve->onClear(1);
        foreach (auto rate, m_rates)
        {
            QDateTime t = QDateTime::fromMSecsSinceEpoch(rate.time);
            double time = QCPAxisTickerDateTime::dateTimeToKey(t);
            m_curve->onAddGraphPoint(1, time, rate.rate.value);
        }
        m_curve->onFullScreen(1);

        QMessageBox::information(this, tr("Tips"), tr("Calculate Interval Rate Finished"));
    });

    m_pbExportIntervalRate = new QPushButton(tr("Export Interval Rate Data"));
    connect(m_pbExportIntervalRate, &QPushButton::clicked, this, [=](){
        ElectronicScaleTool::exportIntervalRateToXlsx(m_importWeightPath, m_rates);
        QMessageBox::information(this, tr("Tips"), tr("Export Interval Rate Finished"));
    });

    QHBoxLayout *hblInterval = new QHBoxLayout();
    hblInterval->addWidget(m_lbInterval);
    hblInterval->addWidget(m_leInterval);

    QHBoxLayout *hblIntervalRate = new QHBoxLayout();
    hblIntervalRate->addWidget(m_pbCalculateIntervalRate);
    hblIntervalRate->addWidget(m_pbExportIntervalRate);

    QVBoxLayout *vblRate = new QVBoxLayout();
    vblRate->addLayout(hblInterval);
    vblRate->addLayout(hblIntervalRate);

    QGroupBox *m_gbRaiseCurve = new QGroupBox();
    m_gbRaiseCurve->setTitle(tr("Raise Curve Setting"));
    m_gbRaiseCurve->setLayout(vblRate);

    // --------------------------------------------------------------------------
    // 喇叭图

    m_lbWhichHour = new QLabel(tr("Which Hour"));
    m_leWhichHour = new QLineEdit();
    m_leWhichHour->setText(QString::number(1));

    m_lbTargetRate = new QLabel(tr("Target Rate(ml/h)"));
    m_leTargetRate = new QLineEdit();
    m_leTargetRate->setText(QString::number(10));

    m_lbDensity = new QLabel(tr("Density(g/ml)"));
    m_leDensity = new QLineEdit();
    m_leDensity->setText(QString::number(0.998));

    m_lbPeriod = new QLabel(tr("Period(min)"));
    m_lePeriod = new QLineEdit();
    m_lePeriod->setText(QString::number(60));
    m_lePeriod->setEnabled(false);

    m_lbSampleInterval = new QLabel(tr("Sample Interval(min)"));
    m_leSampleInterval = new QLineEdit();
    m_leSampleInterval->setText(QString::number(1));
    m_leSampleInterval->setEnabled(false);

    m_pbCalculateHornDiagram = new QPushButton(tr("Calculate Horn Diagram"));
    connect(m_pbCalculateHornDiagram, &QPushButton::clicked, this, [=](){
        if (m_hornDiagram != nullptr)
            delete m_hornDiagram;
        m_hornDiagram = new ElectronicScaleHornDiagram();

        if (m_samples.size() < 2)
            return;

        bool ok;
        double rate = m_leTargetRate->text().toDouble(&ok);
        if (!ok || qFuzzyIsNull(rate))
            return;
        m_hornDiagram->setTargetRate(rate);

        double density = m_leDensity->text().toDouble(&ok);
        if (!ok || qFuzzyIsNull(density))
            return;
        m_hornDiagram->setDensity(density);

        int period = m_lePeriod->text().toInt(&ok);
        if (!ok || period <= 0)
            return;
        m_hornDiagram->setPeriod(period);

        int interval = m_leSampleInterval->text().toInt(&ok);
        if (!ok || interval <= 0)
            return;
        m_hornDiagram->setInterval(interval);

        // 提取指定1小时的数据
        int hour = m_leWhichHour->text().toInt(&ok);
        if (!ok || hour <= 0)
            return;
        qint64 startTime = m_samples.at(0).time;
        qint64 targetStartTime = startTime + (hour - 1) * 3600 * 1000;
        qint64 targetStopTime = targetStartTime + 3600 * 1000;
        int startIndex = ElectronicScaleTool::findIndex(targetStartTime, m_samples);
        int stopIndex = ElectronicScaleTool::findIndex(targetStopTime, m_samples);
        while(1)
        {
            if (m_samples.size() > stopIndex)
            {
                if (m_samples.at(stopIndex).time - m_samples.at(startIndex).time < 3600 * 1000)
                {
                    stopIndex++;
                }
                else
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }
        QList<electronicscale::Sample> samples = m_samples.mid(startIndex, stopIndex - startIndex + 1);
        m_curve->onClear(2);
        foreach (auto s, samples)
        {
            QDateTime t = QDateTime::fromMSecsSinceEpoch(s.time);
            double time = QCPAxisTickerDateTime::dateTimeToKey(t);
            m_curve->onAddGraphPoint(2, time, s.weight.value);
        }
        //m_curve->onFullScreen(2);

        if (!m_hornDiagram->setSamples(samples))
            return;
        m_hornDiagram->calculateViewingWindowErrors(ElectronicScaleHornDiagram::ViewingWindow_2min);
        m_hornDiagram->calculateViewingWindowErrors(ElectronicScaleHornDiagram::ViewingWindow_5min);
        m_hornDiagram->calculateViewingWindowErrors(ElectronicScaleHornDiagram::ViewingWindow_11min);
        m_hornDiagram->calculateViewingWindowErrors(ElectronicScaleHornDiagram::ViewingWindow_19min);
        m_hornDiagram->calculateViewingWindowErrors(ElectronicScaleHornDiagram::ViewingWindow_31min);
        m_hornDiagram->calculateViewingWindowResult();

        QList<ElectronicScaleHornDiagram::ViewingWindowResult> results =
                m_hornDiagram->getViewingWindowResult();
        m_curveHornDiagram->onClear(3);
        foreach (auto r, results)
        {
            m_curveHornDiagram->onAddGraphPoint(0, r.window, r.errorMax);
            m_curveHornDiagram->onAddGraphPoint(1, r.window, r.errorMin);
            m_curveHornDiagram->onAddGraphPoint(2, r.window, r.errorTotal);
        }

        m_curveHornDiagram->onFullScreen(3);
        m_curveHornDiagram->show();

        QMessageBox::information(this, tr("Tips"), tr("Calculate Horn Diagram Finished"));
    });

    m_pbExportHornDiagram = new QPushButton(tr("Export Horn Diagram Data"));
    connect(m_pbExportHornDiagram, &QPushButton::clicked, this, [=](){
        QList<ElectronicScaleHornDiagram::ViewingWindowResult> results =
                m_hornDiagram->getViewingWindowResult();
        ElectronicScaleHornDiagram::exportHornDiagramToXlsx(m_importWeightPath, results, "Horn Diagram");
        QMessageBox::information(this, tr("Tips"), tr("Export Horn Diagram Finished"));
    });

    QHBoxLayout *hblWhichHour = new QHBoxLayout();
    hblWhichHour->addWidget(m_lbWhichHour);
    hblWhichHour->addWidget(m_leWhichHour);
    QHBoxLayout *hblTargetRate = new QHBoxLayout();
    hblTargetRate->addWidget(m_lbTargetRate);
    hblTargetRate->addWidget(m_leTargetRate);
    QHBoxLayout *hblDensity = new QHBoxLayout();
    hblDensity->addWidget(m_lbDensity);
    hblDensity->addWidget(m_leDensity);
    QHBoxLayout *hblPeriod = new QHBoxLayout();
    hblPeriod->addWidget(m_lbPeriod);
    hblPeriod->addWidget(m_lePeriod);
    QHBoxLayout *hblSampleInterval = new QHBoxLayout();
    hblSampleInterval->addWidget(m_lbSampleInterval);
    hblSampleInterval->addWidget(m_leSampleInterval);
    QHBoxLayout *hblHornDiagramCalculate = new QHBoxLayout();
    hblHornDiagramCalculate->addWidget(m_pbCalculateHornDiagram);
    hblHornDiagramCalculate->addWidget(m_pbExportHornDiagram);

    QVBoxLayout *vblHornDiagramSetting = new QVBoxLayout();
    vblHornDiagramSetting->addLayout(hblWhichHour);
    vblHornDiagramSetting->addLayout(hblTargetRate);
    vblHornDiagramSetting->addLayout(hblDensity);
    vblHornDiagramSetting->addLayout(hblPeriod);
    vblHornDiagramSetting->addLayout(hblSampleInterval);
    vblHornDiagramSetting->addLayout(hblHornDiagramCalculate);

    QGroupBox *m_gbHornDiagramCurve = new QGroupBox();
    m_gbHornDiagramCurve->setTitle(tr("Horn Diagram Curve Setting"));
    m_gbHornDiagramCurve->setLayout(vblHornDiagramSetting);

    QVBoxLayout *vblGroup = new QVBoxLayout();
    vblGroup->addWidget(m_pbImportWeight);
    vblGroup->addWidget(m_gbRaiseCurve);
    vblGroup->addWidget(m_gbHornDiagramCurve);

    QHBoxLayout *hbl = new QHBoxLayout();
    hbl->addLayout(vblGroup);
    setLayout(hbl);
}

ElectronicScaleDataProcessPage::~ElectronicScaleDataProcessPage()
{

}
